/*************************************************************************
	> File Name: sigaction_simple.c
	> Author: Angel Criss
	> Blog: blog.abbycin.tk 
	> Created Time: Tue 17 Jun 2014 07:17:52 PM CST
 ************************************************************************/
//在这个程序里面将使用abort()使handler"返回"时不被其杀死,是利用局部跳转退出handler函数
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<setjmp.h>  //利用局部跳转
#include<signal.h>
/*
 *
 * longjmp() 不是 异步信号安全函数 it's unsafe 
 *
 */
static jmp_buf env;  // set a environment to store all program info

void dealing(int sig)
{
    printf("\e\n[36m creat a loop here\e[0m\n");
        int j; /*子进程将会在返回时被主函数中的abort()杀死 */
    for(j=0;j<10;j++){

        printf("\n\n\e[33m the j is :\e[0m\t%d\n\n",j);
        sleep(3);
    }
    printf("\n\n now back to the main function\nbut it can't, because the function 'abort()',\n except use non-locale jump to exit the handler\n\n");
    printf("\n\e[44mnow jump to main()\e[0m\n");
    setjmp(env);
    longjmp(env,(int)main()); // jump to main() to ignore the abort()'s SIGABRT
}

int main()
{
    struct sigaction act;
    sigset_t set;
    int i;
    printf("\nthe PID is:\e[35m %ld\e[0m\n",(long)getpid());
    if(sigemptyset(&set)==-1)
    {
        perror("sigfillset:");
        raise(2);
    }

    printf("\n\e[34m This will handle SIGABRT\e[0m\n");
    act.sa_handler=dealing;
    act.sa_mask=set;
    act.sa_flags=SA_RESTART;
    if(sigaction(SIGABRT,&act,NULL)==-1) // when catch SIGABRT invok the handler function \
        then the handler block SIGUSR1(30,10,16) to see if the function will be termed when the handler return
    {
        perror("sigaction:");
        raise(2);
    }
    printf("\e[32m proccess sleep here for 3s\e[0m\n");
    for(i=0;i<3;i++)
        sleep(1);
    abort(); // make a SIGABRT signal
    for(i=0;;i++){
        printf("\n\n the i is :\t%d\n\n",i);
        sleep(3);
    }
}
